package com.mall.order.services;

import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.OrderShippingMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import com.mall.user.constants.SysRetCodeConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 *  ciggar
 * create-date: 2019/7/30-上午10:05
 */
@Slf4j
@Component
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService {

	@Autowired
	OrderMapper orderMapper;

	@Autowired
	OrderItemMapper orderItemMapper;

	@Autowired
	OrderShippingMapper orderShippingMapper;

	@Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

	@Autowired
	StockMapper stockMapper;


	/**
	 * 创建订单的处理流程
	 *
	 * @param request
	 * @return
	 */
	@Override
	public CreateOrderResponse createOrder(CreateOrderRequest request) {
		CreateOrderResponse response = new CreateOrderResponse();
		try {
			//创建pipeline对象
			TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

			//启动pipeline
			invoker.start(); //启动流程（pipeline来处理）

			//获取处理结果
			AbsTransHandlerContext context = invoker.getContext();

			//把处理结果转换为response
			response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
		} catch (Exception e) {
			log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
			ExceptionProcessorUtils.wrapperHandlerException(response, e);
		}
		return response;
	}

	/**
	 * 取消订单
	 * @param request
	 * @return
	 */
	@Override
	@Transactional
	public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
		CancelOrderResponse response = new CancelOrderResponse();
		try {
			//根据orderId获取到orderItem的数据
			Example example = new Example(OrderItem.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("orderId", request.getOrderId());
			List<OrderItem> orderItems = orderItemMapper.selectByExample(example);

			//更改订单表的状态
			Order order = new Order();
			order.setOrderId(request.getOrderId());
			order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CLOSE);
			orderMapper.updateByPrimaryKeySelective(order);
			for (OrderItem orderItem : orderItems) {
				//查看库存锁定状态
				if (orderItem.getStatus() == 1) {
					orderItem.setStatus(2);
					orderItemMapper.updateByPrimaryKeySelective(orderItem);
					//释放锁定库存
					releaseStock(orderItem.getItemId(),orderItem.getNum());
				}
			}
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
			return response;
		} catch (Exception e) {
			response.setCode(OrderRetCode.SYSTEM_ERROR.getCode());
			response.setMsg(OrderRetCode.SYSTEM_ERROR.getMessage());
			return response;
		}
	}

	private void releaseStock(long itemId,int itemNum) {
		Stock stock = new Stock();
		stock.setItemId(itemId);
		//在数据库的更新语句中执行了库存的加减
		stock.setLockCount(-itemNum);
		stock.setStockCount((long) itemNum);
		stockMapper.updateStock(stock);
	}

	/**
	 * 删除订单
	 * @param request
	 * @return
	 */
	@Override
	@Transactional
	public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
		DeleteOrderResponse response = new DeleteOrderResponse();
		try {
			//校验参数的有效性
			request.requestCheck();
			String orderId = request.getOrderId();

			//判断订单状态,并确定是否释放库存
			Order order = orderMapper.selectByPrimaryKey(orderId);
			if (OrderConstants.ORDER_STATUS_INIT == order.getStatus()) {
				List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
				for (OrderItem orderItem : orderItems) {
					releaseStock(orderItem.getItemId(),orderItem.getNum());
				}
			}
			Example example = new Example(Order.class);
			example.createCriteria().andEqualTo("orderId", orderId);
			int effectedRows = orderMapper.deleteByExample(example);
			if (effectedRows < 1)throw new Exception("删除订单失败");

			Example orderItemExample = new Example(OrderItem.class);
			orderItemExample.createCriteria().andEqualTo("orderId", orderId);
			int effectedRows1 = orderItemMapper.deleteByExample(orderItemExample);
			if (effectedRows1 < 1)throw new Exception("删除订单失败");

			int effectedRows2 = orderShippingMapper.deleteByPrimaryKey(orderId);
			if (effectedRows2 < 1)throw new Exception("删除订单失败");

		}catch (Exception e){
			log.error("OrderQueryServiceImpl.deleteOrder occur Exception :"+e);
			ExceptionProcessorUtils.wrapperHandlerException(response,e);
			return response;
		}
		response.setCode(SysRetCodeConstants.SUCCESS.getCode());
		response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
		return response;
	}

	/**
	 * 支付成功之后,对订单表和库存表的修改
	 * @param PayOrderSuccessRequest
	 * @return
	 */
	@Override
	@Transactional
	public PayOrderSuccessResponse payOrderSuccessAndUpdateOrder(PayOrderSuccessRequest PayOrderSuccessRequest) {
		PayOrderSuccessResponse response = new PayOrderSuccessResponse();
		try {
			PayOrderSuccessRequest.requestCheck();
			//修改订单表的支付状态
			Order order = new Order();
			String orderId = PayOrderSuccessRequest.getOrderId();
			order.setOrderId(orderId);
			order.setUpdateTime(new Date());
			order.setStatus(OrderConstants.ORDER_STATUS_PAYED);
			orderMapper.updateByPrimaryKeySelective(order);

			//根据订单Id查询商品详情
			Example example = new Example(OrderItem.class);
			example.createCriteria().andEqualTo("orderId", orderId);
			List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
			//根据订单商品详情,修改库存
			for (OrderItem orderItem : orderItems) {
				//若库存锁定,扣减库存成功
				if (orderItem.getStatus() == 1) {
					orderItem.setStatus(3);
					orderItemMapper.updateByPrimaryKeySelective(orderItem);
					Stock stock = new Stock();
					stock.setItemId(orderItem.getItemId());
					stock.setLockCount(-orderItem.getNum());
					stock.setStockCount(0L);
					stockMapper.updateStock(stock);
				}

			}
		} catch (Exception e) {
			ExceptionProcessorUtils.wrapperHandlerException(response,e);
			return response;
		}
		response.setCode(OrderRetCode.SUCCESS.getCode());
		response.setMsg(OrderRetCode.SUCCESS.getMessage());
		return response;
	}
}
